package com.jthinker.service.impl;

import com.jthinker.bean.vo.Condition;
import com.jthinker.bean.vo.Constant;
import com.jthinker.bean.vo.QueryResult;
import com.jthinker.bean.vo.SearchFilter;
import com.jthinker.dao.BaseDao;
import com.jthinker.service.CommonService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * User: Gang Chen
 * Date: 2015/3/23 21:44
 */
@Service
public class CommonServiceImpl implements CommonService
{
    @Resource
    private BaseDao baseDao;

    @Override
    public QueryResult<Map<String, Object>> queryTable(SearchFilter filter, String table)
    {
        String sql = "SELECT * FROM " + table;
        return querySql(filter, sql);
    }

    @Override
    public QueryResult<Map<String, Object>> querySql(SearchFilter filter, String sql)
    {
        StringBuilder countSql = new StringBuilder();
        countSql.append("SELECT COUNT(1) FROM (").append(sql).append(") AS RES");

        StringBuilder suffix = new StringBuilder(" WHERE 1=1");
        List<Condition> conditions = filter.getWhere();

        List<Object> params = new ArrayList<Object>();
        if (CollectionUtils.isNotEmpty(conditions))
        {
            for (Condition condition : conditions)
            {
                String field = condition.getField();
                String val = condition.getVal();

                suffix.append(" AND RES.").append(field).append(" ");
                switch (condition.getOp())
                {
                    case EQUAL:
                        suffix.append("=?");
                        params.add(val);
                        break;
                    case LIKE:
                        suffix.append("LIKE ?");
                        params.add("%" + val + "%");
                        break;
                    case LESS:
                        suffix.append("< ?");
                        params.add(val);
                        break;
                    case GREAT:
                        suffix.append("> ?");
                        params.add(val);
                        break;
                    case LESS_OR_EQUAL:
                        suffix.append("<= ?");
                        params.add(val);
                        break;
                    case GREAT_OR_REQUAL:
                        suffix.append(">= ?");
                        params.add(val);
                        break;
                    case IN:
                        String[] arr0 = StringUtils.split(val, Constant.DEFAULT_SEPARATOR);
                        if (arr0 != null && arr0.length > 0)
                        {
                            suffix.append("IN (");
                            for (String str : arr0)
                            {
                                suffix.append("?,");
                                params.add(str);
                            }
                            suffix.deleteCharAt(suffix.length() - 1).append(")");
                        }
                        break;
                    case NOT_IN:
                        String[] arr1 = StringUtils.split(val, Constant.DEFAULT_SEPARATOR);
                        if (arr1 != null && arr1.length > 0)
                        {
                            suffix.append("NOT IN (");
                            for (String str : arr1)
                            {
                                suffix.append("?,");
                                params.add(str);
                            }
                            suffix.deleteCharAt(suffix.length() - 1).append(")");
                        }
                        break;
                }
            }
        }

        countSql.append(suffix);

        Object[] _params = params.toArray();
        Integer total = baseDao.queryForObject(countSql.toString(), Integer.class, _params);

        if (total == null || total.intValue() == 0)
        {
            return QueryResult.EMPTY_RESULT;
        }

        if (StringUtils.isNotBlank(filter.getSort()))
        {
            suffix.append(" ORDER BY ").append(filter.getSort()).append(" ").append(filter.getSortOrder());
        }

        //查询语句
        StringBuilder querySql = new StringBuilder();
        querySql.append("SELECT RES.* FROM (").append(sql).append(") RES");
        querySql.append(suffix);

        List<Map<String, Object>> list = baseDao.queryPagination(querySql.toString(), filter.getPage(), filter.getPageSize(), _params);

        return new QueryResult<Map<String, Object>>(total, list, filter.getPage(), filter.getPageSize());
    }
}
